<template>
  <ElInput
    :modelValue="modelValue"
    :disabled="disabled"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <template #suffix>
      <ElButton
        type="primary"
        link
        :loading="loading"
        :disabled="codeIsValid || disabled"
        @click="sendCode"
      >
        <span v-if="codeIsValid">{{ validTime }}s后可重新发送</span>
        <span v-else>{{ btnText }}</span>
      </ElButton>
    </template>
  </ElInput>
</template>
<script lang="ts" setup generic="P extends Record<string, any>">
import { countDown } from "@/utils";
const props = withDefaults(
  defineProps<{
    modelValue: string;
    /** 发送频率 */
    hz?: number;
    api: (params?: P) => Promise<void>;
    /** 请求参数 */
    params?: P;
    /** 重置标识
     * 内部检测变化以重新计时
     * @example  const resetKey = ref(1);
     * 需要重置时 resetKey.value++;
     *  */
    resetKey?: number;
    /** 是否禁用 */
    disabled?: boolean;
    /** 发送按钮文本 */
    btnText?: string;
  }>(),
  {
    hz: 60,
    btnText: "发送验证码",
  },
);

const emit = defineEmits<(e: "update:modelValue", value: string) => void>();

const validTime = ref(0);

const loading = ref(false);

const codeIsValid = computed(() => {
  return validTime.value > 0;
});

let clearCountDown: () => void;

const sendCode = () => {
  loading.value = true;
  console.log("发送验证码");
  props
    .api(props.params)
    .then(() => {
      validTime.value = props.hz;
      clearCountDown?.();
      clearCountDown = countDown(
        validTime.value,
        (v) => {
          validTime.value = v;
        },
        () => {
          console.log("倒计时结束");
        },
      );
    })
    .finally(() => {
      loading.value = false;
    });
};

onBeforeUnmount(() => {
  clearCountDown?.();
});

watch(
  () => props.resetKey,
  () => {
    clearCountDown?.();
    validTime.value = 0;
  },
);
</script>
